package com.example.io;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * @author readpage
 * @create 2022-10-07 15:37
 *
 * File类的使用
 *
 * 1. File类的一个对象，代表一个文件或一个文件目录(俗称: 文件夹)
 * 2. File类声明在java.io包下
 * 3. File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法，
 *    并文件涉及到写入或读取文件内容的操作，如果需要读取或写入文件内容，必须使用IO流来完成。
 * 4. 后续File类的对象常会作为参数传递到构造器中，指明读取或写入的"终点".
 */
public class FileTest {
    /**
     * 1.如何创建File类的实例
     *     File(String filePath)
     *     File(String parentPath, String childPath)
     *     File(string parentFile, String childPath)
     *
     * 2.
     *  相对路径: 相较于某个路径下，指明的路径。
     *  绝对路径: 包含盘符在内的文件或文件目录的路径
     *  3.路径分隔符
     *  windows: \\
     *  unix: /
     */
    @Test
    public void test() {
        //构造器1
        File file1 = new File("hello.txt.txt"); //相对于当前module
        File file2 = new File("D:\\tmp\\he.txt");

        System.out.println(file1);
        System.out.println(file2);

        //构造器2
        File file3 = new File("D:\\tmp", "java");
        System.out.println(file3);

        File file4 = new File(file3, "hi.txt");
        System.out.println(file4);
    }

    /**
     * public String getAbsolutePath(): 获取绝对路径
     * public String getPath(): 获取路径
     * public String getName(): 获取名称
     * public String getParent(): 获取上层文件目录路径。若无，返回null
     * public long length(): 获取文件长度(即: 字节数)。不能获取目录的长度。
     * public long LastModified(): 获取最后一次的修改时间，毫秒值
     *
     * 如下的两个方法适用于文件目录:
     * public String[] list(): 获取指定目录下的所有文件或文件目录的名称数组
     * public File[] listFiles(): 获取指定目录下的所有文件或者文件目录的File数组
     */
    @Test
    public void test2() {
        File file = new File("hello.txt.txt");
        System.out.println(file.getAbsolutePath());
        System.out.println(file.getPath());
        System.out.println(file.getName());
        System.out.println(file.getParent());
        System.out.println(file.length());
        System.out.println(new Date(file.lastModified()));
    }

    @Test
    public void test3() {
        File file = new File("D:\\code\\Java");
        for (String s : file.list()) {
            System.out.println(s);
        }

        System.out.println();
        for (File listFile : file.listFiles()) {
            System.out.println(listFile);
        }

    }

    /**
     * public boolean renameTo(File dest): 把文件重命名为指定的文件路径
     * 比如 file.renameTo(file2)为例
     *  要像保证返回true,需要file在硬盘是存在的，且file2不能在磁盘中
     */
    @Test
    public void test4() {
        File file = new File("hello.txt.txt");
        File file2 = new File("D:\\tmp\\hi.txt");
        boolean b = file.renameTo(file2);
        System.out.println(b);
    }

    /**
     * public boolean isDirectory(): 判断是否是文件目录
     * public boolean isFile(): 判断是否是文件
     * public boolean exists(): 判断是否存在
     * public boolean canRead(): 判断是否可读
     * public boolean canWrite(): 判断是否可写
     * public boolean isHidden(): 判断是否隐藏
     */
    @Test
    public void test5() {
        File file = new File("hello.txt");
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.canRead());
        System.out.println(file.canWrite());
        System.out.println(file.isHidden());
    }

    /**
     * 创建硬盘中对应的文件或文件目录
     * public boolean createNewFile(): 创建文件。若文件存在，则不创建返回false
     * public boolean mkdir(): 创建文件目录。如果此文件目录存在，就不创建了。如果此文件目录的上层目录不存在，也不创建。
     * public boolean mkdirs(): 创建文件目录。如果上层文件目录不存在，一并创建
     *
     * 删除磁盘中的文件或文件目录
     * public boolean delete(): 删除文件或者文件夹
     * 删除注意事项:
     * Java中的删除不走回收站。
     */
    @Test
    public void test6() throws IOException {
        //文件的创建
        File file = new File("hi.txt");
        if (!file.exists()) {
            file.createNewFile();
            System.out.println("创建成功");
        } else {
            // 文件存在
            file.delete();
            System.out.println("删除成功");
        }

    }

    @Test
    public void test7() {
        //文件目录的创建
        File file = new File("D:\\tmp\\io\\io");
        boolean mkdir = file.mkdir();
        if (mkdir) {
            System.out.println("创建成功");
        }

        File file2 = new File("D:\\tmp\\io\\io");
        boolean mkdir2 = file.mkdirs();
        if (mkdir2) {
            System.out.println("创建成功!");
        }

        //要想删除成功，io目录下不能有子目录或文件
        File file3 = new File("D:\\tmp\\io\\io2");
        System.out.println(delete(file3));
    }
    
    // 扩展2: 删除指定的目录或文件
    public boolean delete(File file) {
        // 如果file是文件，直接delete
        // 如果file是目录，先把它的下一级干掉，然后删除自己
        if (file.isDirectory()) {
            // 循环删除的是file的下一级
            for (File f : file.listFiles()) {
                delete(f);
            }
        }
        // 删除自己
        return file.delete();
    }
}
